package face.pay.security.config;

import face.pay.security.filter.BeforeLoginFilter;
import face.pay.security.filter.UserNamePassWordLoginFilter;
import face.pay.security.handler.FaceAuthenctiationSuccessHandler;
import face.pay.security.provider.UserNamePassWordProvider;
import face.pay.security.session.ExpiredSessionFilter;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.web.servlet.ServletListenerRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.core.session.SessionRegistry;
import org.springframework.security.core.session.SessionRegistryImpl;
import org.springframework.security.web.authentication.*;
import org.springframework.security.web.authentication.logout.LogoutSuccessHandler;
import org.springframework.security.web.authentication.logout.SimpleUrlLogoutSuccessHandler;
import org.springframework.security.web.authentication.www.BasicAuthenticationFilter;
import org.springframework.security.web.session.ConcurrentSessionFilter;
import org.springframework.security.web.session.HttpSessionEventPublisher;
import org.springframework.security.web.session.SessionInformationExpiredStrategy;

@EnableWebSecurity
public class FaceSecurityConfig extends WebSecurityConfigurerAdapter {


    @Autowired
    @Qualifier("authenticationManagerBean")
    private AuthenticationManager authenticationManager;

    @Autowired
    UserNamePassWordProvider userNamePassWordProvider;

    @Autowired
    SessionInformationExpiredStrategy sessionRegistry;

    //拦截请求
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        //设置哪些url允许被某种角色访问
        http.csrf().disable();

        http.authorizeRequests().
                antMatchers("/timeOut").permitAll()
                .antMatchers("/login").permitAll()
                .antMatchers("/images/**").permitAll()
                .antMatchers("/css/**").permitAll()
                .antMatchers("/js/**").permitAll()
                .antMatchers("/json/**").permitAll()
                .antMatchers("/layui/**").permitAll()
                .antMatchers("/page/**").permitAll()
                .antMatchers("/json/**").permitAll()
                .antMatchers("/video/**").permitAll()
                .antMatchers("/echarts/**").permitAll()
                .antMatchers("/vue/**").permitAll()
                .antMatchers("/forGet/**").permitAll()
                .antMatchers("/**").hasAnyRole("USER","ADMIN","OEM_MANAGER","AGENCY_MANAGER","ENTERPRISE_MANAGER","COMPANY_MANAGER")
                .antMatchers("/").hasAnyRole("USER","ADMIN","OEM_MANAGER","AGENCY_MANAGER","ENTERPRISE_MANAGER","COMPANY_MANAGER")
                .anyRequest().authenticated();

        //启用登录功能，可以使用默认的登录页，这里使用自定义的login.html页面
            http.formLogin().loginPage("/login");

            http.logout().logoutUrl("/logout").logoutSuccessUrl("/login");

            http.sessionManagement().maximumSessions(1).maxSessionsPreventsLogin(true).expiredSessionStrategy(sessionRegistry);
            http.httpBasic();
            //达到最大数禁止登录（预防并发登录）
            http.headers().frameOptions().sameOrigin();
            http.addFilterBefore(userNamePassWordLoginFilter(), UsernamePasswordAuthenticationFilter.class);
            //http.addFilterBefore(concurrentSessionFilter(),BasicAuthenticationFilter.class);
        // http.addFilterAt(userNamePassWordLoginFilter(),UsernamePasswordAuthenticationFilter.class);


          //启用rememberMe功能，将用户信息保存在cookie中
            http.rememberMe();
    }

    //授权认证
    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
       auth.authenticationProvider(userNamePassWordProvider);
    }

    @Override
    @Bean
    public AuthenticationManager authenticationManagerBean() throws Exception {
        return super.authenticationManagerBean();
    }




    /*@Bean
    public  BeforeLoginFilter beforeLoginFilter() {
        BeforeLoginFilter filter = new BeforeLoginFilter();
        return filter;
    }*/

    @Bean
    public UserNamePassWordLoginFilter userNamePassWordLoginFilter() {
        UserNamePassWordLoginFilter filter = new UserNamePassWordLoginFilter();
        filter.setAuthenticationFailureHandler(authenticationFailureHandler());
        filter.setAuthenticationSuccessHandler(authenticationSuccessHandler());
        filter.setAuthenticationManager(authenticationManager);
        return filter;
    }

    public ExpiredSessionFilter concurrentSessionFilter() {
        ExpiredSessionFilter filter = new ExpiredSessionFilter();

        return filter;
    }

    @Bean
    public SimpleUrlAuthenticationSuccessHandler authenticationSuccessHandler() {
        return new SimpleUrlAuthenticationSuccessHandler("/index");
    }

    @Bean
    public AuthenticationFailureHandler authenticationFailureHandler() {
        SimpleUrlAuthenticationFailureHandler failureHandler =  new SimpleUrlAuthenticationFailureHandler("/login?error=true");

        return failureHandler;

    }

    @Bean
    public SessionRegistry getSessionRegistry(){
        SessionRegistry sessionRegistry=new SessionRegistryImpl();

        return sessionRegistry;
    }

    @Bean
    public ServletListenerRegistrationBean httpSessionEventPublisher() {
        return new ServletListenerRegistrationBean(new HttpSessionEventPublisher());
    }


    @Bean
    public LogoutSuccessHandler logoutSuccessHandler() {
        return new SimpleUrlLogoutSuccessHandler();
    }



}
